
#include <d3dx9.h>
#include <cegfx/celodnodecollection.h>


ceLODNodeCollection::ceLODNodeCollection ()
	: ceNodeCollection ()
	, solver (0)
	, lodStage (0)
{
	IQF_CONSTRUCT;
}

ceLODNodeCollection::~ceLODNodeCollection ()
{
}

IQF_IMPLEMENTATION_BEGIN(ceLODNodeCollection);
//IQF_IMPLEMENTATION_INTERFACE(iDynamicContent);
IQF_IMPLEMENTATION_END ();


void ceLODNodeCollection::SetLODSolver (iLODSolver* solver)
{
	SAVE_SET(this->solver, solver);
}

iLODSolver* ceLODNodeCollection::GetLODSolver () 
{
	return solver;
}

const iLODSolver* ceLODNodeCollection::GetLODSolver () const
{
	return solver;
}

void ceLODNodeCollection::Update (const ceUpdateEnv& env)
{

	// based on the given lod stage solver the current lod Stage 
	// is evaluated... 
	// if no solver is given the stage 0 (the stage with the most details) 
	// wil be used.
	if (solver)
	{
		static D3DXVECTOR3 v;
		// calculate the squared distance between the camera location
		// and the center of this collection
		const D3DXMATRIX& m = GetTransform ().GetMatrix ();
		v.x = m._41;
		v.y = m._42;
		v.z = m._43;
		D3DXVec3Subtract (&v, &v, &env.CameraPosition);
		float sqrDist = D3DXVec3Dot (&v, &v);

		lodStage = solver->Solve(sqrDist);
		
		unsigned size = nodes.size();
		if (lodStage >= size && keepLastNode)
		{
			// if the last node should be kept, 
			// use this last node.
			lodStage = size - 1;
		}
	}
	else
	{
		lodStage = 0;
	}
}

void ceLODNodeCollection::SetKeepLastNode (bool keepLastNode)
{
	this->keepLastNode = keepLastNode;
}

bool ceLODNodeCollection::IsKeepLastNode () const
{
	return keepLastNode;
}


unsigned ceLODNodeCollection::GetNumberOfNodes () const
{
	unsigned size = nodes.size ();
	if (size != 0 && lodStage < size)
	{
		return 1;
	}

	return 0;
}

ceNodePtr ceLODNodeCollection::GetNode (unsigned idx) 
{
	unsigned size = nodes.size ();
	if (size == 0 || lodStage >= size)
	{
		return 0;
	}

	return nodes [lodStage];
}

const ceNodePtr ceLODNodeCollection::GetNode (unsigned idx)  const
{
	unsigned size = nodes.size ();
	if (size == 0 || lodStage >= size)
	{
		return 0;
	}

	return nodes [lodStage];
}

